package l1j.opqlo.Server.L1World;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;

import l1j.server.server.model.Instance.L1MonsterInstance;
import l1j.server.server.model.map.L1Map;
import l1j.server.server.types.Point;


/**
 * 世界MOB暫存區<BR>
 *
 * @author dexc
 *
 */
public class WorldMob {

	private static final Logger _log = Logger.getLogger(WorldMob.class.getName());

	private static WorldMob _instance;

	public static WorldMob get() {
		if (_instance == null) {
			_instance = new WorldMob();
		}
		return _instance;
	}

	private final ConcurrentHashMap<Integer, L1MonsterInstance> _isMob;

	private Collection<L1MonsterInstance> _allMobValues;

	private WorldMob() {
		this._isMob = new ConcurrentHashMap<Integer, L1MonsterInstance>();
	}

	/**
	 * 全部怪物
	 * @return
	 */
	public Collection<L1MonsterInstance> all() {
		try {
			final Collection<L1MonsterInstance> vs = this._allMobValues;
			return vs != null ? vs : (this._allMobValues = Collections.unmodifiableCollection(this._isMob.values()));

		} catch (final Exception e) {
			_log.log(Level.WARNING,e.getLocalizedMessage(), e);
		}
		return null;
	}

	/**
	 * 19格範圍內相同NPC物件數量
	 * @param src 原始物件
	 * @return
	 */
	public int getVisibleCount(final L1MonsterInstance src) {
		final L1Map map = src.getMap();
		final Point pt = src.getLocation();
		int count = 0;

		for (L1MonsterInstance element : this.all()) {
			//for (final L1MonsterInstance element : this._isMob.values()) {
			if (element.equals(src)) {
				continue;
			}
			if (map != element.getMap()) {
				continue;
			}
			// 19格內NPC
			if (pt.isInScreen(element.getLocation())) {
				if (src.getNpcId() == element.getNpcId()) {
					count++;
				}
			}
		}

		return count;
	}

	/**
	 * 19格範圍NPC物件
	 * @param src 原始物件
	 * @return
	 */
	public ArrayList<L1MonsterInstance> getVisibleMob(final L1MonsterInstance src) {
		final L1Map map = src.getMap();
		final Point pt = src.getLocation();
		final ArrayList<L1MonsterInstance> result = new ArrayList<L1MonsterInstance>();

		for (L1MonsterInstance element : this.all()) {
			//for (final L1MonsterInstance element : this._isMob.values()) {
			if (element.equals(src)) {
				continue;
			}
			if (map != element.getMap()) {
				continue;
			}
			// 19格內NPC
			if (pt.isInScreen(element.getLocation())) {
				result.add(element);
			}
		}

		return result;
	}

	/**
	 * 怪物清單
	 * @return
	 */
	public ConcurrentHashMap<Integer, L1MonsterInstance> map() {
		return this._isMob;
	}

	/**
	 * 加入怪物清單
	 * @param key
	 * @param value
	 */
	public void put(final Integer key, final L1MonsterInstance value) {
		try {
			if(this._isMob.get(key)!=null){
				_log.log(Level.WARNING,"怪物清單重複添加物件\r\n怪物清單重複添加物件\r\n怪物清單重複添加物件\r\n怪物清單重複添加物件");
			}
			this._isMob.put(key, value);

		} catch (final Exception e) {
			_log.log(Level.WARNING,e.getLocalizedMessage(), e);
		}
	}

	/**
	 * 移出怪物清單
	 * @param key
	 */
	public void remove(final Integer key) {
		try {
			this._isMob.remove(key);

		} catch (final Exception e) {
			_log.log(Level.WARNING,e.getLocalizedMessage(), e);
		}
	}
}
